package api

import (
	"context"
	"errors"
	"fmt"
	"log"
	"longmen/server/config/global"
	cache3 "longmen/server/internal/rpc/tencentim/cache"
	_const "longmen/server/pkg/common/helper/const"
	"longmen/server/pkg/common/helper/encrypt"
	string2 "longmen/server/pkg/common/helper/string"
	time2 "longmen/server/pkg/common/helper/timehelper"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/common/services"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/db/mysql/models/models_live"
	"longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/redis/cache"
	"longmen/server/pkg/grpc_client"
	"longmen/server/pkg/protobuf"
	"time"

	"longmen/server/pkg/common/api_models"

	"github.com/labstack/echo/v4"
	"github.com/spf13/cast"
	"gorm.io/gorm"
)

// @Summary 直播页菜单
// @Description 直播页菜单
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} protobuf.MenusResp "result"
// @Router /api/live/liveMenus [POST]
func (base *Controller) LiveMenus(c echo.Context) error {
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.Menus(ctx, &protobuf.Empty{})
	if err != nil {
		global.Log.Errorf("%v", resp, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 判断是否是直播间管理员
// @Description 判断是否是直播间管理员
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.CheckIsMgrReq true "body"
// @Success 200 {object} protobuf.PermissionResp "result"
// @Router /api/live/checkIsMgr [POST]
func (base *Controller) CheckIsMgr(c echo.Context) error {
	r := &api_models.CheckIsMgrReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}

	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.Permission(ctx, &protobuf.PermissionReq{
		UserId:       int64(user.Id),
		AnchorId:     int64(r.Anchorid),
		TargetUserId: int64(r.TargetUserID),
	})

	if err != nil {
		return util.BuildSuccess(c, resp, err.Error())
	}
	return util.BuildSuccess(c, resp, "")

}

// @Summary 获取直播列表
// @Description 获取直播列表
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.GetLiveListReq true "body"
// @Success 200 {object} protobuf.LiveListResp "result"
// @Router /api/live/getLiveList [POST]
func (base *Controller) GetLiveList(c echo.Context) error {
	var (
		err error
		req = &api_models.GetLiveListReq{}
	)
	channel := base.GetRegSource(c)
	platform := int32(base.GetPlatform(c))
	//global.Log.Debugf("c.Path():%v", c.Path())
	////平台号强制为1很怪, 不知道是什么作用, 不影响先去掉
	//if c.Path() == "/api/live/getAppLiveList" {
	//	platform = 1
	//}
	if err = util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LiveList(
		ctx,
		&protobuf.LiveListReq{
			Page:       uint32(string2.GetDefaultNum(req.Page, 1)),
			Size:       uint32(string2.GetDefaultNum(req.Size, 20)),
			Categoryid: uint32(req.Categoryid),
			Cateid:     uint32(req.CateID),
			ClientIp:   c.RealIP(),
			Uid:        int64(req.UID),
			Platform:   platform,
			Channel:    channel,
		},
	)
	if err != nil {
		return util.BuildFail(c, 1, "数据请求出错", err)
	}
	if resp == nil || resp.LiveList == nil {
		return util.BuildSuccess(c, []interface{}{}, "")
	}
	return util.BuildSuccess(c, resp.LiveList, "")
}

// @Summary 获取直播列表,带分页条数
// @Description 获取直播列表,带分页条数
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.GetLiveListReq true "body"
// @Success 200 {object} protobuf.LiveListResp "result"
// @Router /api/live/list [POST]
func (base *Controller) LiveListPagination(c echo.Context) error {
	var (
		err error
		req = &api_models.GetLiveListReq{}
	)

	if err = util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BadParam(c, err)
	}
	//if err = util.Validate.Struct(req); err != nil {
	//	global.Log.Errorf("6GetLiveList9参数错误%v", err)
	//	return common.BadParam(c, err)
	//}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LiveList(
		ctx,
		&protobuf.LiveListReq{
			Page:       uint32(string2.GetDefaultNum(req.Page, 1)),
			Size:       uint32(string2.GetDefaultNum(req.Size, 20)),
			Categoryid: uint32(req.Categoryid),
			Cateid:     uint32(req.CateID),
			ClientIp:   c.RealIP(),
			Uid:        int64(req.UID),
			Platform:   int32(base.GetPlatform(c)),
			Channel:    base.GetRegSource(c),
		},
	)

	if err != nil {
		return util.BuildFail(c, 1, "数据请求出错", err)
	}
	if resp == nil || resp.LiveList == nil {
		return util.BuildSuccess(c, []interface{}{}, "")
	}

	return util.BuildSuccess(c, resp, "")

}

// @Summary 根据赛事ID查询主播列表
// @Description 根据赛事ID查询主播列表
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.GetLiveListReq true "body"
// @Success 200 {object} protobuf.LiveListResp "result"
// @Router /api/live/getMatchLiveList [POST]
func (base *Controller) GetMatchLiveList(c echo.Context) error {
	r := &api_models.GetLiveListReq{}
	uid, _ := c.Get(_const.HTTP_KEY_UID).(int)
	/*if uid <= 0 {
		return common.BadParam(c, errors.New("请登陆"))
	}*/
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	r.Page = string2.GetDefaultNum(int(r.Page), 1)
	r.Size = string2.GetDefaultNum(int(r.Size), 20)
	if uid <= 0 {
		uid = r.UID
	}
	if r.Categoryid <= 0 {
		return util.BuildFail(c, _const.RPC_FAILED, "请输入正确的赛事ID", errors.New("请输入正确的赛事ID"))
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.MatchLiveList(ctx, &protobuf.LiveListReq{Page: uint32(r.Page), Size: uint32(r.Size), Categoryid: uint32(r.Categoryid), Cateid: uint32(uid), Uid: int64(uid), ClientIp: c.RealIP()})
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	if resp.GetLiveList() == nil {
		return util.BuildSuccess(c, []interface{}{}, "")
	}
	return util.BuildSuccess(c, resp.GetLiveList(), "")
}

// @Summary 获取直播分类
// @Description 获取直播分类
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} models_live.LiveCategory "result"
// @Router /api/live/getCategory [POST]
func (base *Controller) GetCategory(c echo.Context) error {
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	lives, err := grpc_client.GrpcLiveServer.GetCategory(ctx, &protobuf.Empty{})
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	return util.BuildSuccess(c, lives.SummaryCategory, "")
}

// @Summary 获取直播分类 mobile
// @Description 获取直播分类 mobile
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} models_live.LiveCategory "result"
// @Router /api/live/getBaseCategory [POST]
func (base *Controller) GetBaseCategory(c echo.Context) error {
	headChannel := c.Request().Header.Get("reg-source")
	platform := base.GetPlatform(c)
	lives, err := base.Service.GetBaseCategory(headChannel, platform)
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	return util.BuildSuccess(c, lives, "")
}

// @Summary 获取直播间页信息
// @Description 获取直播间页信息
// @Accept  json
// @Produce  json
// @Tags Live
// @Param reg-source header string true "渠道号"
// @Param   sendBody body api_models.GetLivePageDataReq true "body"
// @Success 200 {object} api_models.GetLivePageDataResp "result"
// @Router /api/live/getLivePageData [POST]
func (base *Controller) GetLivePageData(c echo.Context) error {
	r := &api_models.GetLivePageDataReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BuildFail(c, 1, "", err)
	}

	r.DeviceInfo = c.Request().Header.Get("device-info")
	r.Platform = cast.ToInt8(c.Request().Header.Get("platform"))
	if r.DeviceInfo == "" {
		r.DeviceInfo = "nil"
	}

	headChannel := c.Request().Header.Get("reg-source")
	if len(headChannel) > 0 {
		cache.NewStatUserWatch().RecordUser(headChannel, c.RealIP())
		cache3.IncGlobalLiveRoomIp(c.RealIP())
	}

	cache.SetDeviceInfo(r, c.RealIP())

	if r.Uid <= 0 {
		r.Uid = cast.ToInt(c.Get("uid"))
	}

	// result, err := base.Service.GetLivePageData(r, c.RealIP())
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	result, err := grpc_client.GrpcLiveServer.LiveData(ctx, &protobuf.LiveDataReq{
		Anchorid:   int64(r.Anchorid),
		Platform:   int32(r.Platform),
		DeviceInfo: r.DeviceInfo,
		ClientIp:   c.RealIP(),
		Uid:        int64(r.Uid),
	})
	//global.Log.Debugf("GetLivePageData resp:+%v", result)
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}

	// es channel
	services.UserChannel2ES(fmt.Sprintf("%d", result.Live.Liveid), r.DeviceInfo, r.Channel)
	return util.BuildSuccess(c, result, "")
}

// @Summary 修改直播
// @Description 修改直播
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.EditLiveReq true "body"
// @Success 200 {object} models_live.Live "result"
// @Router /api/live/editLive [POST]
func (base *Controller) EditLive(c echo.Context) error {

	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	if user.IsAnchor == 0 {
		return util.BuildFail(c, 1, "该账号尚未认证主播", nil)
	}

	r := &api_models.EditLiveReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}

	msg, live, err := base.Service.EditLive(r, user)
	if err != nil {
		return util.BuildFail(c, 1, msg, err)
	}
	return util.BuildSuccess(c, live, "")
}

// @Summary 取得推流地址
// @Description 取得推流地址
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} api_models.GetStreamInfoResp "result"
// @Router /api/live/getStreamInfo [POST]
func (base *Controller) GetStreamInfo(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	if user.IsAnchor == 0 {
		return util.BuildFail(c, 1, "该账号尚未认证主播", nil)
	}
	i, err := db_main.CheckBannedlive(user.Id)
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	if i == 0 {
		return util.BuildFail(c, 1, "您已经被永久封禁!", err)
	}
	if i > 0 && time.Now().Unix() < int64(i) {
		return util.BuildFail(c, 1, fmt.Sprintf("您已经被封禁至%s", time2.Stamp2Time(int64(i)).Format(time2.TIME_LAYOUT_FORMAT_4)), err)
	}
	stream, pushUrl, pullUrl, anchorSecret, webRtcPushUrl, flvPushUrl := base.Service.GetStreamInfo(user)
	resp := &api_models.GetStreamInfoResp{
		Stream:        stream,
		PushUrl:       pushUrl,
		WebRtcPushUrl: webRtcPushUrl,
		PullUrl:       pullUrl,
		AnchorSecret:  anchorSecret,
		FlvPushUrl:    flvPushUrl,
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 開始直播
// @Description 開始直播
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.StartLiveReq true "body"
// @Success 200 {object} models_live.Live "result"
// @Router /api/live/startLive [POST]
func (base *Controller) StartLive(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	global.Log.Errorf("USER==>%+v", user)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	r := &api_models.StartLiveReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	if r.StartStamp > 0 && time.Now().Unix()-300 > r.StartStamp {
		return util.BuildFail(c, 1, "开播时间已失效", nil)
	}
	live, err := base.Service.StartLive(r, user, &api_models.LivePlugins{
		LiveStatus: int(cache.PauseLive),
	})
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	p := &protobuf.CreateGroupReq{AnchorId: int32(user.Id), UserId: int32(user.Id), GroupName: cast.ToString(r.MatchId)}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.CreteGroup(ctx, p)
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	return util.BuildSuccess(c, live, "")
}

// @Summary 結束直播
// @Description 結束直播
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} api_models.Response "result"
// @Router /api/live/endLive [POST]
func (base *Controller) EndLive(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.EndLive(ctx, &protobuf.EndLiveReq{
		AnchorId: int64(user.Id),
	})
	global.Log.Debugf("endLive resp:%v,err:%v", resp, err)
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	return util.BuildSuccess(c, nil, resp.String())
}

// @Summary 直播贡献排行榜
// @Description 直播贡献排行榜
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.GetContributeRankReq true "body"
// @Success 200 {object} api_models.GetContributeRankResp "result"
// @Router /api/live/getContributeRank [POST]
func (base *Controller) GetContributeRank(c echo.Context) error {
	r := &protobuf.ContributeRankReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.ContributeRank(ctx, r)
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	if len(resp.GetContributeRank()) == 0 {
		return util.BuildSuccess(c, []interface{}{}, "")
	}
	return util.BuildSuccess(c, resp.ContributeRank, "")
}

// @Summary 热门直播间
// @Description 热门直播间
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.HotLiveReq true "body"
// @Success 200 {object} protobuf.HotLiveResp "result"
// @Router /api/live/hotLive [POST]
func (base *Controller) HotLive(c echo.Context) error {

	r := &api_models.GetHotLiveIReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.HotLive(ctx, &protobuf.HotLiveReq{Uid: uint32(r.Uid), ClientIp: c.RealIP(), Platform: 1})
	if err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	return util.BuildSuccess(c, resp.HotLive, "")
}

// 直播回调
func (base *Controller) LiveCallback(c echo.Context) error {
	fName := "LiveCallback"
	body, ok := c.Get("body").(string)

	global.Log.Debugf("%s body :%s", util.Convert(fName), body)
	if !ok {
		global.Log.Errorf("直播回调失败 %s body not a string\n", util.Convert(fName))
		return util.BadParam(c, errors.New("body not a string"))
	}

	r := &api_models.LiveCallbackReq{}
	if err := util.Json2Struct(body, r); err != nil {
		global.Log.Errorf("直播回调失败 %s Json2Struct fail err :%s\n", util.Convert(fName), err.Error())
		return util.BadParam(c, err)
	}

	sign := encrypt.Md5(fmt.Sprintf("%s%d", _const.StreamCallBackKey, r.T))
	if sign != r.Sign {
		global.Log.Errorf("直播回调失败 %s key :%s r.T :%d r.Sign :%s sign :%s\n",
			util.Convert(fName), _const.StreamCallBackKey, r.T, r.Sign, sign)
		return util.BuildFail(c, 1, "", fmt.Errorf("%s sign not valid", util.Convert(fName)))
	}

	err := base.Service.LiveCallback(r)
	if err != nil {
		global.Log.Errorf("直播回调失败 %s %s\n", util.Convert(fName), err.Error())
		return util.BuildFail(c, 1, "", err)
	}
	return util.BuildSuccess(c, nil, "")
}

//// @Summary 推荐直播间
//// @Description 推荐直播间
//// @Accept  json
//// @Produce  json
//// @Tags Live
//// @Param   sendBody body api_models.GetHotRecommendLiveReq true "body"
//// @Success 200 {object} api_models.HotRecommendLive "result"
//// @Router /api/live/hotRecommendLive [POST]
//func (this *Controller) HotRecommendLive(c echo.Context) error {
//	r := &api_models.GetHotRecommendLiveReq{}
//	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
//		return common.BadParam(c, err)
//	}
//	if err := util.Validate.Struct(r); err != nil {
//		return common.BadParam(c, err)
//	}
//	resp, err := this.Service.HotRecommendLive(r.Categoryid)
//	if err != nil {
//		return common.BuildFail(c, 1, "", err)
//	}
//	return common.BuildSuccess(c, resp, "")
//}

// @Summary 写入直播间访问记录
// @Description 写入直播间访问记录
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.LiveVisitRecordReq true "body"
// @Success 200 {object} api_models.LiveVisitRecordResp "result"
// @Router /api/live/visit_record [POST]
func (base *Controller) LiveVisitRecord(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	r := &api_models.LiveVisitRecordReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LiveVisitRecord(ctx, &protobuf.LiveVisitRecordReq{
		Liveid:   uint64(r.LiveID),
		UserId:   uint64(user.Id),
		Platform: uint32(r.Platform),
	})
	if err != nil {
		if err != gorm.ErrRecordNotFound {
			global.Log.Errorf("%v", resp, err)
		}
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 直播间访问记录列表
// @Description 直播间访问记录列表
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.LiveVisitListReq true "body"
// @Success 200 {object} protobuf.LiveVisitResp "result"
// @Router /api/live/visit_list [POST]
func (base *Controller) LiveVisitList(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	r := &api_models.LiveVisitListReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LiveVisitList(ctx, &protobuf.LiveVisitReq{
		UserId: uint64(user.Id),
		Page:   uint32(r.Page),
		Size:   uint32(r.Size),
		Status: uint32(r.Status),
	})
	if err != nil {
		global.Log.Errorf("%v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 清除直播间访问记录
// @Description 清除直播间访问记录
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.LiveVisitCleanReq true "body"
// @Success 200 {object} protobuf.LiveVisitRecordResp "result"
// @Router /api/live/visit_clean [POST]
func (base *Controller) LiveVisitClean(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LiveVisitClean(ctx, &protobuf.LiveVisitCleanReq{
		UserId: uint64(user.Id),
	})
	if err != nil {
		global.Log.Errorf("%v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 官方直播间
// @Description 官方直播间
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.OfficialLiveReq true "body"
// @Success 200 {object} protobuf.OfficialLiveResp "result"
// @Router /api/live/official_live [POST]
func (base *Controller) OfficialLiveRoom(c echo.Context) error {
	r := &protobuf.OfficialLiveReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if r.GetMatchId() < 1 {
		return util.BadParam(c, errors.New("matchid not null"))
	}
	r.ClientIp = c.RealIP()
	r.Platform = int32(base.GetPlatform(c))
	//global.Log.Debugf("platform:%d", r.GetPlatform())
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.OfficialLiveRoom(ctx, r)
	if err != nil {
		global.Log.Errorf("%v,err:%v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 用户背包道具
// @Description 用户背包道具
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.UserBackpackReq true "body"
// @Success 200 {object} protobuf.UserBackpackResp "result"
// @Router /api/live/user_backpack [POST]
func (base *Controller) GetUserBackpack(c echo.Context) error {
	r := &protobuf.UserBackpackReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.UserBackpack(ctx, &protobuf.UserBackpackReq{
		UserId: cast.ToInt64(c.Get("uid")),
	})
	if err != nil {
		global.Log.Errorf("%v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 用户背包道具选用挂件最多三个其他一个
// @Description 用户背包道具选用挂件最多三个其他一个
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.UserBackpackSetSelectedReq true "body"
// @Success 200 {object} protobuf.UserBackpackSetSelectedResp "result"
// @Router /api/live/user_set_backpack [POST]
func (base *Controller) SetUserBackpack(c echo.Context) error {
	//user, err := base.GetUserByCtx(c)
	//if err != nil {
	//	return common.BuildLoginTimeOut(c, err)
	//}
	r := &protobuf.UserBackpackSetSelectedReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.UserBackpackSetSelected(ctx, &protobuf.UserBackpackSetSelectedReq{
		Type:   r.Type,
		UserId: cast.ToInt64(c.Get("uid")),
		Ids:    r.Ids,
		Sel:    r.Sel,
	})
	if err != nil {
		global.Log.Errorf("%v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// 工会分成测试
func (base *Controller) GuildShareTest(c echo.Context) error {

	var params = &api_models.SendGiftReq{
		Anchorid: 6000167,
		Giftid:   48,
		Liveid:   1664516318167,
		Count:    1,
		Uid:      6010810,
	}

	//resp, err := services.SendGift(params, 6012547)
	resp, err := services.SendGiftSubtract(params, 6010810)
	log.Println("9SendGift6 ERR:", err)
	log.Println("9Live6 SendGift Resp:", resp)
	// repository.GuildShareBalance(6000000, 1000)
	if err != nil {
		return util.BuildSuccess(c, nil, fmt.Sprintf("%v", err))
	}
	return util.BuildSuccess(c, nil, fmt.Sprintf("%v", resp))
}

// @Summary 主播中心直播统计数据
// @Description 主播中心直播统计数据
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.LiveStatReq true "body"
// @Success 200 {object} protobuf.LiveStatSummaryResp "result"
// @Router /api/live/live_stat [POST]
func (base *Controller) AnchorLiveStat(c echo.Context) error {
	r := &protobuf.LiveStatReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.AnchorLiveStat(ctx, &protobuf.LiveStatReq{
		AnchorId:  cast.ToInt64(c.Get("uid")),
		StartDate: r.StartDate,
		EndDate:   r.EndDate,
		Size:      r.Size,
	})
	if err != nil {
		global.Log.Errorf("%+v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 主播中心直播历史场次
// @Description 主播中心直播历史场次
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.LiveHistoryReq true "body"
// @Success 200 {object} protobuf.LiveHistoryResp "result"
// @Router /api/live/live_history [POST]
func (base *Controller) LiveHistory(c echo.Context) error {
	r := &protobuf.LiveHistoryReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LiveHistory(ctx, &protobuf.LiveHistoryReq{
		Id:        cast.ToInt64(c.Get("uid")),
		StartDate: r.StartDate,
		EndDate:   r.EndDate,
	})
	if err != nil {
		global.Log.Errorf("%+v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 主播中心我的观众
// @Description 主播中心我的观众
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.LiveVisitorReq true "body"
// @Success 200 {object} protobuf.LiveVisitorResp "result"
// @Router /api/live/live_visitor [POST]
func (base *Controller) LiveVisitor(c echo.Context) error {
	r := &protobuf.LiveVisitorReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LiveVisitor(ctx, &protobuf.LiveVisitorReq{
		Id:        cast.ToInt64(c.Get("uid")),
		StartDate: r.StartDate,
		EndDate:   r.EndDate,
		Sort:      r.Sort,
		LastTime:  r.LastTime,
		Page:      r.Page,
		Size:      r.Size,
	})
	if err != nil {
		global.Log.Errorf("%+v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// 主播收入统计测试
// @Summary 达人榜
// @Description 达人榜
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.TopUserReq true "body"
// @Success 200 {object} protobuf.TopUserResp "result"
// @Router /api/live/top_user [POST]
func (base *Controller) TopUser(c echo.Context) error {
	r := &protobuf.TopUserReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	resp, err := grpc_client.GrpcLiveServer.TopUser(context.Background(), &protobuf.TopUserReq{
		Type:     r.Type,
		DateType: r.DateType,
		UserId:   r.UserId,
	})
	if err != nil {
		global.Log.Errorf("%+v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 达人榜说明
// @Description 达人榜说明
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body api_models.TopUserDescReq true "body"
// @Success 200 {object} api_models.TopUserDescResp "result"
// @Router /api/live/top_user_desc [POST]
func (base *Controller) TopUserDesc(c echo.Context) error {
	r := &api_models.TopUserDescReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	resp, err := db_main.TopUserDesc(r.ID)
	if err != nil {
		global.Log.Errorf("%+v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// 聊天室相关测试
//func (base *Controller) ChatTest(c echo.Context) error {
//	/*
//		resp, err := grpc_client.WebSocketClient.BanUser(context.Background(), &pt.BanUserReq{
//			Userid:   6010751,
//			Type:     1,
//			Anchorid: 6010751,
//			BanUid:   6021832,
//			BanTime:  timehelper.Now().Add(timehelper.Hour * 1).Unix(),
//		})
//
//		log.Printf("ChatTest resp: %+v", resp)
//		log.Printf("ChatTest err: %+v", err)
//	*/
//	oRes, err := services.ChatRoomGetUserInfo(&api_models.UserInfoReq{
//		Uid:      int32(6022955),
//		AnchorId: int64(6021402),
//	})
//	global.Log.Debugf("%v\n-----\n%v", oRes, err)
//	return err
//}

// @Summary 获取当前直播所有房间信息
// @Description 获取当前直播所有房间信息
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} protobuf.LiveSeoResp "result"
// @Router /api/live/getLiveSeoList [POST]
func (base *Controller) GetLiveSeoList(c echo.Context) error {
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.GetLiveSeoList(ctx, &protobuf.Empty{})
	if err != nil {
		global.Log.Errorf("%+v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "suc")
}

// @Summary 使用限时道具目前只有一种(坐骑)
// @Description 使用限时道具目前只有一种(坐骑)
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.UseBackPackPropsReq true "body"
// @Success 200 {object} protobuf.UserBackpackResp "result"
// @Router /api/live/useBackPackProps [POST]
func (base *Controller) UseBackPackProps(c echo.Context) error {
	r := &protobuf.UseBackPackPropsReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	r.UserId = cast.ToInt64(c.Get("uid"))
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.UseBackPackProps(ctx, r)
	if err != nil || resp.Code == _const.RPC_FAILED {
		global.Log.Errorf("%v%v", resp, err)
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp.Code, "succeed")
}

////主播收入统计测试
//func (base *Controller) AnchorLiveStatTest(c echo.Context) error {
//	resp, err := repository.AnchorIncome(6010858, "2022-07-24")
//	log.Println("GetAnchorIncome ERR:", err)
//	log.Println(" GetAnchorIncome Resp:", resp)
//	// repository.GuildShareBalance(6000000, 1000)
//	if err != nil {
//		return common.BuildSuccess(c, nil, fmt.Sprintf("%v", err))
//	}
//	return common.BuildSuccess(c, nil, fmt.Sprintf("%v", resp))
//}

// @Summary 聊天室风控配置
// @Description 聊天室风控配置
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} protobuf.ChatConfigResp "result"
// @Router /api/live/chat_config [POST]
func (base *Controller) ChatConfig(c echo.Context) error {
	r := &protobuf.ChatConfigResp{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.ChatConfig(ctx, &protobuf.Empty{})
	if err != nil {
		return util.BuildFail(c, _const.RPC_FAILED, _const.EMPTY_STR, err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 入场票扣票或已扣票入场
// @Description 入场票扣票或已扣票入场
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} protobuf.ChatConfigResp "result"
// @Router /api/live/ticket [POST]
func (base *Controller) Ticket(c echo.Context) error {
	r := &protobuf.TicketReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.Ticket(ctx, r)
	if err != nil {
		return util.BuildFail(c, _const.RPC_FAILED, err.Error(), err)
	}

	return util.BuildSuccess(c, resp, "")
}

// @Summary 发观看券
// @Description 发观看券
// @Accept  json
// @Produce  json
// @Tags Search
// @Param   sendBody body protobuf.ProvideTicketReq true "body"
// @Success 200 {object} protobuf.ProvideTicketResp "result"
// @Router /api/live/provide_ticket [POST]
func (base *Controller) ProvideTicket(c echo.Context) error {
	r := &protobuf.ProvideTicketReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.ProvideTicket(ctx, r)
	if err != nil {
		return util.BuildFail(c, _const.RPC_FAILED, err.Error(), err)
	}

	return util.BuildSuccess(c, resp, "")
}

// @Summary 使用记录
// @Description 观看卷列表
// @Accept  json
// @Produce  json
// @Tags Search
// @Param   sendBody body protobuf.TicketListReq true "body"
// @Success 200 {object} protobuf.TicketListResp "result"
// @Router /api/live/ticket_list [POST]
func (base *Controller) TicketList(c echo.Context) error {
	r := &protobuf.TicketListReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.TicketList(ctx, r)
	if err != nil {
		return util.BuildFail(c, _const.RPC_FAILED, err.Error(), err)
	}

	return util.BuildSuccess(c, resp, "")
}

func (base *Controller) LiveRecordCall(c echo.Context) error {
	fName := "直播录制回调"
	body, ok := c.Get("body").(string)
	if !ok {
		global.Log.Errorf("%s body not a string\n", fName)
		return util.BadParam(c, errors.New("body not a string"))
	}
	r := &api_models.LiveRecordCallReq{}
	if err := util.Json2Struct(body, r); err != nil {
		global.Log.Errorf("%s Json2Struct fail err :%s\n", fName, err.Error())
		return util.BadParam(c, err)
	}
	if r.EventType == "NewFileUpload" { //上传完成时
		mediaUrl := r.FileUploadEvent.MediaBasicInfo.MediaUrl
		fileId := r.FileUploadEvent.FileId
		fileName := r.FileUploadEvent.MediaBasicInfo.Name //推流地址取出流id,关联主播用 例""261334_1693377360_2023-08-30-14-39-02_2023-08-30-14-40-06"
		global.Log.Debugf("fileId:%v,fileName:%v,mediaUrl:%v", fileId, fileName, mediaUrl)

		anchorID, title, stream, err := base.Service.AnchorLiveHis(fileName)
		if err != nil {
			global.Log.Debugf("AnchorLiveHis err:%v, mediaUrl:%v", err.Error(), mediaUrl)
			return util.BuildSuccess(c, err, err.Error())
		}

		// 计算时长
		hour := int(r.FileUploadEvent.MetaData.Duration) / 3600
		min := (int(r.FileUploadEvent.MetaData.Duration) % 3600) / 60
		sec := (int(r.FileUploadEvent.MetaData.Duration) % 3600) % 60

		err = base.Service.Record2Video(&models_live.Video{
			AnchorID:    anchorID,
			PlayURL:     mediaUrl,
			Title:       title,
			Type:        models_main.LiveRecordType, //录制回放
			CallbackReq: body,
			TCFileID:    fileId,
			Stream:      stream,
			Duration:    fmt.Sprintf("%d:%d:%d", hour, min, sec),
			CreateTime:  time.Now().Unix(),
		})

		if err != nil {
			return util.BuildSuccess(c, err, err.Error())
		}

	} else if r.EventType == "FileDeleted" { //文件删除时

	}
	global.Log.Debugf("%s body :%s", fName, body)
	return util.BuildSuccess(c, "ok", "")
}

// @Summary 活动是否开启查询
// @Description 活动是否开启查询
// @Accept  json
// @Produce  json
// @Tags Live
// @Success 200 {object} protobuf.ChatConfigResp "result"
// @Router /api/live/activity [POST]
func (base *Controller) Activity(c echo.Context) error {
	r := &api_models.ActivityReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	resp, err := base.Service.Activity(r.AnchorID)
	if err != nil {
		return util.BuildSuccess(c, err, err.Error())
	}

	return util.BuildSuccess(c, resp, "")
}

// @Summary 直播预告
// @Description 直播预告
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.LivePreviewReq true "body"
// @Success 200 {object} protobuf.LivePreviewResp "result"
// @Router /api/live/preview [POST]
func (base *Controller) Preview(c echo.Context) error {
	r := &protobuf.LivePreviewReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.LivePreview(ctx, r)
	if err != nil {
		return util.BuildFail(c, _const.RPC_FAILED, err.Error(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 直播预告
// @Description 直播预告
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.AnchorDetailReq true "body"
// @Success 200 {object} protobuf.AnchorDetailResp "result"
// @Router /api/live/anchor_detail [POST]
func (base *Controller) AnchorDetail(c echo.Context) error {
	r := &protobuf.AnchorDetailReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	user, _ := base.GetUserByCtx(c)
	r.Uid = int64(user.Id)
	resp, err := grpc_client.GrpcLiveServer.AnchorDetail(ctx, r)
	if err != nil {
		return util.BuildFail(c, _const.RPC_FAILED, err.Error(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 直播回放
// @Description 直播回放
// @Accept  json
// @Produce  json
// @Tags Live
// @Param   sendBody body protobuf.AnchorReplayReq true "body"
// @Success 200 {object} protobuf.AnchorReplayResp "result"
// @Router /api/live/anchor_repplay [POST]
func (base *Controller) AnchorReplay(c echo.Context) error {
	r := &protobuf.AnchorReplayReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcLiveServer.AnchorReplay(ctx, r)
	if err != nil {
		return util.BuildFail(c, _const.RPC_FAILED, err.Error(), err)
	}
	return util.BuildSuccess(c, resp, "")
}
